package com.qidian.buy.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qidian.buy.entity.Content;
import com.qidian.buy.mapper.ContentMapper;
import com.qidian.buy.service.IContentService;
import com.qidian.buy.util.Const;
import com.qidian.buy.util.JSONTools;
import com.qidian.buy.util.data.ThreadStorage;
import com.qidian.buy.util.pojo.LayuiTableDTO;
import com.qidian.buy.util.pojo.QDResult;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @Author 郭浩
 */
@Service
public class ContentServiceImpl implements IContentService {

    @Resource
    private ContentMapper contentMapper;
    @Value("${content-cache-key}")
    private String contentCacheKey;
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    public QDResult save(Content content) {
        // 清空缓存
        stringRedisTemplate.delete(contentCacheKey);
        // 补全数据
        QDResult result = saveIn(content);
        //  启动子线程清理缓存
        Thread t = new Thread(()->{
            try {
                Thread.sleep(100);
                // 清空缓存
                stringRedisTemplate.delete(contentCacheKey);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        // 将删除的线程放在一个集合中
        ThreadStorage.push(t);
        t.start();
        return result;
    }
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public QDResult saveIn(Content content){
        content.setCreated(new Date());
        content.setUpdated(new Date());
        content.setStatus(Const.STATUS_NORMAL);
        int result  = contentMapper.insert(content);
        // 清理缓存......
        return result == 1?QDResult.ok(content):QDResult.fal();
    }

    public QDResult edit(Content content){
        // 清空缓存
        stringRedisTemplate.delete(contentCacheKey);
        QDResult result = editIn(content);
        //  启动子线程清理缓存
        Thread t = new Thread(()->{
            try {
                Thread.sleep(100);
                // 清空缓存
                stringRedisTemplate.delete(contentCacheKey);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        // 将删除的线程放在一个集合中
        ThreadStorage.push(t);
        t.start();
        return result;
    };
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public QDResult editIn(Content content){
        // 补全数据
        content.setUpdated(new Date());
        return contentMapper.updateById(content)==1?QDResult.ok(content):QDResult.fal();
    }

    @Override
    public QDResult delete(Content content) {
        if (contentMapper.updateById(content)==1){
            return QDResult.ok();
        }
        return QDResult.fal();
    }

    public QDResult<Content> get(Long id){
        Content content = contentMapper.selectById(id);
        if(content!=null)
            return QDResult.ok(content);
        return QDResult.notFound();
    }

    @Override
    public LayuiTableDTO<Content> query(int page,int limit,Content content) {
        LayuiTableDTO<Content> dto = new LayuiTableDTO<>();
        IPage<Content> pager = new Page<>();
        pager.setCurrent(page);
        pager.setSize(limit);
        QueryWrapper<Content> wrapper = new QueryWrapper<>();
        // 组织查询条件
        if(content != null) {
            wrapper.like(content.getTitle()!=null && !content.getTitle().equals(""),"title", content.getTitle());
            wrapper.eq(content.getType()!=null && content.getType()!=0,"type",content.getType());
            wrapper.eq(content.getStatus()!=null && content.getStatus()!=0,"status",content.getStatus());
        }
        pager = contentMapper.selectPage(pager,wrapper);
        dto.setCount(pager.getTotal());
        dto.setData(pager.getRecords());
        return dto;
    }

    @Override
    public QDResult load(){
        // 加载数据
        Map data = new HashMap();
        // 从redis查询数据
        if(stringRedisTemplate.hasKey(contentCacheKey)) {
            String json = stringRedisTemplate.opsForValue().get(contentCacheKey);
            if(json != null && !json.equals("")){
                try {
                    Map map = JSONTools.json2object(json, Map.class);
                    data = map;
                    // 转换成功直接返回
                    return QDResult.ok(data);
                } catch (Exception e) {
                    //
                }
            }
        }
        // 逐个查询
        QueryWrapper<Content> wrapper = new QueryWrapper<>();
        wrapper.eq("type",Const.CONTENT_CAT_LUNBO);
        data.put("lunbo",contentMapper.selectList(wrapper));
        //----
        wrapper = new QueryWrapper<>();
        wrapper.eq("type",Const.CONTENT_CAT_BANNER);
        List banners = contentMapper.selectList(wrapper);
        data.put("banner",banners!=null && banners.size()>0 ? banners.get(0):null);
        //----
        wrapper = new QueryWrapper<>();
        wrapper.eq("type",Const.CONTENT_CAT_CATEGORY);
        data.put("catCategory",contentMapper.selectList(wrapper));
        //----
        wrapper = new QueryWrapper<>();
        wrapper.eq("type",Const.CONTENT_CAT_CENTER);
        data.put("center",contentMapper.selectList(wrapper));
        //----
        wrapper = new QueryWrapper<>();
        wrapper.eq("type", Const.CONTENT_CAT_DANPING);
        data.put("danping",contentMapper.selectList(wrapper));
        //----
        wrapper = new QueryWrapper<>();
        wrapper.eq("type",Const.CONTENT_CAT_TUIJIAN);
        data.put("tuijian",contentMapper.selectList(wrapper));
        // 返回之前，先进行缓存
        stringRedisTemplate.opsForValue().set(contentCacheKey, JSONTools.object2json(data));
        stringRedisTemplate.expire(contentCacheKey,30+new Random().nextInt(10), TimeUnit.MINUTES);
        return QDResult.ok(data);
    };
}
